/* Copyright (c) 2025 Beijing Semidrive Technology Corporation
 * SPDX-License-Identifier: Apache-2.0
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
/** *****************************************************************************************************
 * \file     Mcu_Pll.c                                                                                  *
 * \brief    AUTOSAR 4.3.1 MCAL Mcu Driver                                                              *
 *                                                                                                      *
 * <table>                                                                                              *
 * <tr><th>Date           <th>Version                                                                   *
 * <tr><td>2023/08/02     <td>1.0.0                                                                     *
 * </table>                                                                                             *
 *******************************************************************************************************/
/********************************************************************************************************
 *                                      Include header files                                            *
 *******************************************************************************************************/
#include "RegHelper.h"
#include "Mcu_Pll.h"
#include "Mcu_GeneralTypes.h"
#include "Mcu_Cfg.h"

#define MCU_START_SEC_CODE
#include "Mcu_MemMap.h"
/********************************************************************************************************
 *                                  Private Function Declarations                                       *
 *******************************************************************************************************/
#if (MCU_PLL_SPREAD == STD_ON)
/** *****************************************************************************************************
 * \brief Set PLL spread amplitude.
 *
 * \verbatim
 * Syntax             : static void Mcu_Ip_PllSetSscAmplitude(uint32 base, Mcu_CkgenSscAmplitudeType amplitude)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - PLL base address
 *                      amplitude - SSC amplitude 0-31 represents 0.1% - 3.2%.
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : This function set SSC amplitude for specific pll.
 *
 * \endverbatim
 *******************************************************************************************************/
static void Mcu_Ip_PllSetSscAmplitude(uint32 base, Mcu_CkgenSscAmplitudeType amplitude)
{
    uint32 value;

    value = readl(base + PLL_DSM_OFF);

    value &= ~FM_PLL_DSM_SSC_DEP;
    value |= FV_PLL_DSM_SSC_DEP(amplitude);

    writel(value, base + PLL_DSM_OFF);

    return;
}

/** *****************************************************************************************************
 * \brief Set PLL spread frequency.
 *
 * \verbatim
 * Syntax             : static void Mcu_Ip_PllSetSscFrequency(uint32 base, Mcu_CkgenSscFreqType sscFreq)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - PLL base address
 *                      sscFreq - SSC modulation frequency.
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : This function set SSC frequency for specific pll.
 *
 * \endverbatim
 *******************************************************************************************************/
static void Mcu_Ip_PllSetSscFrequency(uint32 base, Mcu_CkgenSscFreqType sscFreq)
{
    uint32 value;

    value = readl(base + PLL_DSM_OFF);

    value &= ~FM_PLL_DSM_SSC_FREQ;
    value |= FV_PLL_DSM_SSC_FREQ(sscFreq);

    writel(value, base + PLL_DSM_OFF);
}

/** *****************************************************************************************************
 * \brief Set PLL spread mode.
 *
 * \verbatim
 * Syntax             : static void Mcu_Ip_PllSetSscMode(uint32 base, Mcu_CkgenSscModeType sscMode)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - PLL base address
 *                      sscMode - SSC mode.
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : None
 *
 * Description        : This function set SSC mode for specific pll.
 *
 * \endverbatim
 *******************************************************************************************************/
static void Mcu_Ip_PllSetSscMode(uint32 base, Mcu_CkgenSscModeType sscMode)
{
    uint32 value;

    value = readl(base + PLL_DSM_OFF);

    value &= ~FM_PLL_DSM_SSC_MODE;
    value |= FV_PLL_DSM_SSC_MODE(sscMode);

    writel(value, base + PLL_DSM_OFF);
}
#endif
/** *****************************************************************************************************
 * \brief This function set/cancle PLL force bypass.
 *
 * \verbatim
 * Syntax             : void Mcu_Ip_PllForceBypass(uint32 base, boolean enable)
 *
 * Service ID[hex]    : -
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : enable - TRUE- set pll bypass; FALSE- cancel pll bypass.
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : -
 *
 * Description        : This function set/cancle PLL force bypass.
 *                      Pll force bypass, pll output force to fs24M refclock.
 *                      set and cancle need use in pairs.
 * \endverbatim
 * Traceability       : SWSR_MCU_004
 *******************************************************************************************************/
static void Mcu_Ip_PllForceBypass(uint32 base, boolean enable)
{
    uint32 ctrlVal = readl(base + PLL_CTL_OFF);
    uint32 pdStatus;
    uint32 rstStatus;
    uint32 bypassStatus;

    if (TRUE == enable)
    {
        pdStatus = (ctrlVal & BM_PLL_CTL_PD);
        rstStatus = (ctrlVal & BM_PLL_CTL_RESETN);

        if ((0U == pdStatus) && (rstStatus != 0U))
        {
            ctrlVal |= BM_PLL_CTL_FORCE_BYPASS;
            writel(ctrlVal, (base + PLL_CTL_OFF));
        }
    }
    else
    {
        bypassStatus = (ctrlVal & BM_PLL_CTL_FORCE_BYPASS);

        if (bypassStatus != 0U)
        {
            ctrlVal &= ~BM_PLL_CTL_FORCE_BYPASS;
            writel(ctrlVal, (base + PLL_CTL_OFF));
        }
    }
}

/** *****************************************************************************************************
 * \brief calculate the m/n value.
 *
 * \verbatim
 * Syntax             : static Std_ReturnType Mcu_Ip_PllVcoGetBestMNValue(Mcu_PllRateType srcRate, Mcu_PllRateType rate, uint32 *mValPtr, uint32 *nValPtr)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : srcRate - parent rate
 *                      rate - rate to set
 *
 * Parameters (inout) : mValPtr - pointer to m value
 *                      nValPtr - pointer to n value
 *
 * Parameters (out)   : None
 *
 * Return value       : errID
 *
 * Description        : calculate the m/n value.
 *
 * \endverbatim
 *******************************************************************************************************/
static Std_ReturnType Mcu_Ip_PllVcoGetBestMNValue(Mcu_PllRateType srcRate, Mcu_PllRateType rate,
        uint32 *mValPtr, uint32 *nValPtr)
{
    uint64 vcoOut;
    uint32 fracVal;
    uint64 tmpU64;
    Std_ReturnType errStatus = E_OK;

    vcoOut = rate;

    if ((vcoOut > PLL_VCO_FMAX) || (vcoOut < PLL_VCO_FMIN))
    {
        errStatus = MCU_E_PARAM_CONFIG;
    }
    else
    {
        vcoOut /= 2U;
        *nValPtr = (uint32)(vcoOut / srcRate);
        fracVal = (uint32)(vcoOut % srcRate);

        /* integer mode */
        if (0U == fracVal)
        {
            *mValPtr = 0U;
        }
        else
        {
            /* fractional mode */
            tmpU64 = (uint64)fracVal << 24U;
            tmpU64 = (tmpU64 / (uint64)srcRate);

            *mValPtr = (uint32)tmpU64;
        }
    }

    return errStatus;
}

/** *****************************************************************************************************
 * \brief Select the optimal postdiv.
 *
 * \verbatim
 * Syntax             : static Std_ReturnType Mcu_Ip_PllVcoGetBestPostDiv(Mcu_PllRateType vcoRate, Mcu_PllRateType ckRate,
                                                                            uint32 *postDivPtr)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : vcoRate - parent rate
 *                      ckRate - rate to set
 *
 * Parameters (inout) : postDivPtr - pointer to post div
 *
 * Parameters (out)   : None
 *
 * Return value       : errID
 *
 * Description        : Select the optimal postdiv.
 *
 * \endverbatim
 *******************************************************************************************************/
static Std_ReturnType Mcu_Ip_PllVcoGetBestPostDiv(Mcu_PllRateType vcoRate, Mcu_PllRateType ckRate,
        uint32 *postDivPtr)
{
    uint32 i;
    Std_ReturnType errStatus = E_OK;

    *postDivPtr = Mcu_Ip_CkgenGetBestDiv(vcoRate, ckRate);

    if (UINT32_MAX == *postDivPtr)
    {
        errStatus = MCU_E_PARAM_CONFIG;
    }
    else
    {
        for (i = (uint32)MCU_PLL_POST_DIVIDER_2; i < (uint32)MCU_PLL_POST_DIVIDER_MAX; i++)
        {
            if (((i + 1U) * 2U) == *postDivPtr)
            {
                *postDivPtr = i;
                break;
            }
        }

        if (i == (uint32)MCU_PLL_POST_DIVIDER_MAX)
        {
            errStatus = MCU_E_PARAM_CONFIG;
        }
    }

    return errStatus;
}

/********************************************************************************************************
 *                                  Global Function Declarations                                        *
 *******************************************************************************************************/
/** *****************************************************************************************************
 * \brief pll enable and cancel pybass.
 *
 * \verbatim
 * Syntax             : Std_ReturnType Mcu_Ip_PllVcoEnable(uint32 base)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - PLL base address
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : errId
 *
 * Description        : pll enable and cancel pybass.
 *
 * \endverbatim
 *******************************************************************************************************/
Std_ReturnType Mcu_Ip_PllVcoEnable(uint32 base)
{
    Std_ReturnType errStatus = E_OK;
    uint32 reg = base + PLL_CTL_OFF;
    uint32 val;

    /* write m_ready for pll pd clear m_ready value and analog need m_ready to sample m value*/
    val = readl(base + PLL_M_NUM_OFF);

    if (0U == (val & BM_PLL_M_NUM_M_READY))
    {
        val |= BM_PLL_M_NUM_M_READY;
        writel(val, base + PLL_M_NUM_OFF);
    }

    /*pll analog on*/
    val = readl(reg);

    val |= BM_PLL_CTL_RESETN;
    val &= ~BM_PLL_CTL_PD;

    writel(val, reg);

    /*wait pll status lock*/
    if (FALSE == Mcu_Ip_WaitForBitTimes(base + PLL_STATUS_OFF, BM_PLL_STATUS_LOCK, 1U,
                                        PLL_WAIT_TIME))
    {
        errStatus = MCU_E_TIMEOUT;
    } /* else not needed */

    /*cancel pll forcebypass*/
    Mcu_Ip_PllForceBypass(base, FALSE);

    return errStatus;
}

/** *****************************************************************************************************
 * \brief pll bypass and disable.
 *
 * \verbatim
 * Syntax             : void Mcu_Ip_PllVcoDisable(uint32 base)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - PLL base address
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : errId
 *
 * Description        : pll bypass and disable.
 *
 * \endverbatim
 *******************************************************************************************************/
void Mcu_Ip_PllVcoDisable(uint32 base)
{
    uint32 reg = base + PLL_CTL_OFF;
    uint32 val;

    /*pll force bypass*/
    Mcu_Ip_PllForceBypass(base, TRUE);

    /*pll analog off*/
    val = readl(reg);

    val &= ~BM_PLL_CTL_RESETN;
    val |= BM_PLL_CTL_PD;

    writel(val, reg);
}
/** *****************************************************************************************************
 * \brief Vco pll prepare rate, include pll vco rate and pll ck0/ck1 output rate.
 *
 * \verbatim
 * Syntax             : Std_ReturnType Mcu_Ip_PllVcoPrepare(uint32 base, Mcu_PllRateType srcRate, Mcu_PllRateType vcoRate,
 *                      Mcu_PllRateType ck0Rate, Mcu_PllRateType ck1Rate, const Mcu_PllSpreadConfigType *spreadConfigPtr)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - PLL base address
 *                      srcRate - parent rate
 *                      vcoRate - vco rate to set
 *                      ck0Rate - pll ck0 output rate to set
 *                      ck1Rate - pll ck1 output rate to set
 *                      spreadConfigPtr - pointer to spread config
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : errId
 *
 * Description        : Vco pll prepare rate, include pll vco rate and pll ck0/ck1 output rate.
 *
 * \endverbatim
 * Traceability       : SW_SM005 SW_MCU_SM011
 *******************************************************************************************************/
/* PRQA S 3206 2 */
Std_ReturnType Mcu_Ip_PllVcoPrepare(uint32 base, Mcu_PllRateType srcRate, Mcu_PllRateType vcoRate,
                                    Mcu_PllRateType ck0Rate, Mcu_PllRateType ck1Rate, const Mcu_PllSpreadConfigType *spreadConfigPtr)
{
    uint32 ctrlVal;
    uint32 mRegVal;
    uint32 nRegVal;
    uint32 mVal = 0U;
    uint32 nVal = 0U;
    Std_ReturnType errStatus;
    boolean dsmEn = FALSE;
    uint32 postDivCk0 = 0U;
    uint32 postDivCk1 = 0U;

    errStatus = Mcu_Ip_PllVcoGetBestMNValue(srcRate, vcoRate, &mVal, &nVal);

    if (E_OK == errStatus)
    {
        errStatus = Mcu_Ip_PllVcoGetBestPostDiv(vcoRate, ck0Rate, &postDivCk0);

        if (E_OK == errStatus)
        {
            errStatus = Mcu_Ip_PllVcoGetBestPostDiv(vcoRate, ck1Rate, &postDivCk1);

            if (E_OK == errStatus)
            {
                Mcu_Ip_PllVcoDisable(base);

#if (MCU_PLL_SPREAD == STD_ON)
                /* set PLL_DSM config*/
                if (NULL_PTR != spreadConfigPtr)
                {
                    Mcu_Ip_PllSetSscAmplitude(base, spreadConfigPtr->amplitude);
                    Mcu_Ip_PllSetSscFrequency(base, spreadConfigPtr->frequency);
                    Mcu_Ip_PllSetSscMode(base, spreadConfigPtr->mode);
                    dsmEn = TRUE;
                }
#endif
                /* set PLL_N_NUM_OFF/PLL_M_NUM_OFF & PLL_M_READY */
                nRegVal = readl(base + PLL_N_NUM_OFF);
                nRegVal &= ~FM_PLL_N_NUM_N_NUM;
                nRegVal |= FV_PLL_N_NUM_N_NUM(nVal);
                writel(nRegVal, base + PLL_N_NUM_OFF);

                mRegVal = readl(base + PLL_M_NUM_OFF);
                mRegVal &= ~FM_PLL_M_NUM_M_NUM;
                mRegVal |= (FV_PLL_M_NUM_M_NUM(mVal) | BM_PLL_M_NUM_M_READY);
                writel(mRegVal, base + PLL_M_NUM_OFF);

                ctrlVal = readl(base + PLL_CTL_OFF);

                /* PRQA S 2996 1 */
                if ((mVal != 0U) || (TRUE == dsmEn))
                {
                    ctrlVal &= ~BM_PLL_CTL_DSM_DISABLE;
                }
                else
                {
                    ctrlVal |= BM_PLL_CTL_DSM_DISABLE;
                }

                /*LOCK_MODE need alaways be set to 0, fractional mode, to improve robustness,
                when set to 1, pll unlock may occur at low temperatures*/
                ctrlVal &= ~BM_PLL_CTL_LOCK_MODE;

                ctrlVal &= ~FM_PLL_CTL_VCO_BAND;

                if (vcoRate >= PLL_VCO_BAND)
                {
                    ctrlVal |= FV_PLL_CTL_VCO_BAND(7U);
                }
                else
                {
                    ctrlVal |= FV_PLL_CTL_VCO_BAND(4U);
                }

                writel(ctrlVal, base + PLL_CTL_OFF);

                /* set POST_DIV_CLK0 and POST_DIV_CLK1 */
                ctrlVal = readl(base + PLL_POST_DIV_OFF);

                ctrlVal &= ~FM_PLL_POST_DIV_POST_DIV_CLK_0;
                ctrlVal |= FV_PLL_POST_DIV_POST_DIV_CLK_0(postDivCk0);

                ctrlVal &= ~FM_PLL_POST_DIV_POST_DIV_CLK_1;
                ctrlVal |= FV_PLL_POST_DIV_POST_DIV_CLK_1(postDivCk1);

                writel(ctrlVal, base + PLL_POST_DIV_OFF);

                errStatus = Mcu_Ip_PllVcoEnable(base);

            } /* else not needed */
        } /* else not needed */
    } /* else not needed */

    return errStatus;
}

/** *****************************************************************************************************
 * \brief pll ck0/ck1 output rate prepare.
 *
 * \verbatim
 * Syntax             : Std_ReturnType Mcu_Ip_PllCkPrepare(uint32 base, Mcu_PllRateType srcRate, Mcu_PllRateType rate, uint32 id)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - PLL base address
 *                      srcRate - parent rate
 *                      rate - pll ck output rate to set
 *                      id - pll ck0/ck1 id
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : errId
 *
 * Description        : pll ck0/ck1 output rate prepare.
 *
 * \endverbatim
 * Traceability       : SW_SM005 SW_MCU_SM011
 *******************************************************************************************************/
Std_ReturnType Mcu_Ip_PllCkPrepare(uint32 base, Mcu_PllRateType srcRate,
                                   Mcu_PllRateType rate, uint32 id)
{
    uint32 ctrlVal;
    uint32 postDiv = 0U;
    Std_ReturnType errStatus;

    errStatus = Mcu_Ip_PllVcoGetBestPostDiv(srcRate, rate, &postDiv);

    if (E_OK == errStatus)
    {
        ctrlVal = readl(base + PLL_POST_DIV_OFF);

        if (PLL_ID_NUM_VCO_CLK_0 == id)
        {
            ctrlVal &= ~FM_PLL_POST_DIV_POST_DIV_CLK_0;
            ctrlVal |= FV_PLL_POST_DIV_POST_DIV_CLK_0(postDiv);
        }
        else if (PLL_ID_NUM_VCO_CLK_1 == id)
        {
            ctrlVal &= ~FM_PLL_POST_DIV_POST_DIV_CLK_1;
            ctrlVal |= FV_PLL_POST_DIV_POST_DIV_CLK_1(postDiv);
        }
        else
        {
            errStatus = MCU_E_PARAM_CONFIG;
        }

        if (E_OK == errStatus)
        {

            Mcu_Ip_PllVcoDisable(base);

            writel(ctrlVal, base + PLL_POST_DIV_OFF);

            errStatus = Mcu_Ip_PllVcoEnable(base);
        }

    } /* else not needed */

    return errStatus;
}

/** *****************************************************************************************************
 * \brief pll check locked.
 *
 * \verbatim
 * Syntax             : boolean Mcu_Ip_PllIsLocked(uint32 base)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - PLL base address
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : pll lock state
 *
 * Description        : get the pll lock state.
 *                      return 1 means in lock, 0 means unlock.
 *
 * \endverbatim
 *******************************************************************************************************/
boolean Mcu_Ip_PllIsLocked(uint32 base)
{
    boolean ret;

    if (0U != (readl(base + PLL_STATUS_OFF) & BM_PLL_STATUS_LOCK))
    {
        ret = TRUE;
    }
    else
    {
        ret = FALSE;
    }

    return ret;
}

/** *****************************************************************************************************
 * \brief pll vco frequency get
 * .
 *
 * \verbatim
 * Syntax             : Mcu_PllRateType Mcu_Ip_PllGetVcoRate(uint32 base, Mcu_PllRateType srcRate)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - pll base address
 *                      srcRate - pll parent rate
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : pll vco frequency
 *
 * Description        : pll vco frequency get
 * .
 * \endverbatim
 *******************************************************************************************************/
Mcu_PllRateType Mcu_Ip_PllGetVcoRate(uint32 base, Mcu_PllRateType srcRate)
{
    Mcu_PllRateType fVco;
    uint32 val;
    uint32 mVal;
    uint32 nVal;
    uint32 tmpU32;
    uint64 tmpU64;

    val = readl(base + PLL_N_NUM_OFF);

    nVal = GFV_PLL_N_NUM_N_NUM(val);

    tmpU32 = srcRate * 2U;
    fVco = tmpU32 * nVal;

    val = readl(base + PLL_M_NUM_OFF);

    mVal = GFV_PLL_M_NUM_M_NUM(val);
    tmpU64 = (uint64)tmpU32 * (uint64)mVal;
    fVco += (uint32)(tmpU64 >> 24U);

    return fVco;
}

/** *****************************************************************************************************
 * \brief pll ck output frequency get
 * .
 *
 * \verbatim
 * Syntax             : Mcu_PllRateType Mcu_Ip_PllGetCkRate(uint32 base, uint32 id, Mcu_PllRateType srcRate)
 *
 * Service ID[hex]    : None
 *
 * Sync/Async         : Synchronous
 *
 * Reentrancy         : Non reentrant
 *
 * Parameters (in)    : base - pll base address
 *                      id - pll ck0/ck1 id
 *                      srcRate - pll parent rate
 *
 * Parameters (inout) : None
 *
 * Parameters (out)   : None
 *
 * Return value       : pll ck output frequency
 *
 * Description        : pll ck output frequency get
 * .
 * \endverbatim
 *******************************************************************************************************/
Mcu_PllRateType Mcu_Ip_PllGetCkRate(uint32 base, uint32 id, Mcu_PllRateType srcRate)
{
    uint32 reg = base + PLL_POST_DIV_OFF;
    Mcu_PllRateType fCk = UINT32_MAX;
    uint32 val;
    uint32 postDiv;
    uint32 i;

    val = readl(reg);

    if (PLL_ID_NUM_VCO_CLK_0 == id)
    {
        postDiv = GFV_PLL_POST_DIV_POST_DIV_CLK_0(val);
    }
    else if (PLL_ID_NUM_VCO_CLK_1 == id)
    {
        postDiv = GFV_PLL_POST_DIV_POST_DIV_CLK_1(val);
    }
    else
    {
        postDiv = UINT32_MAX;
    }

    if (UINT32_MAX != postDiv)
    {
        for (i = (uint32)MCU_PLL_POST_DIVIDER_2; i < (uint32)MCU_PLL_POST_DIVIDER_MAX; i++)
        {
            if (postDiv == i)
            {
                postDiv = ((i + 1U) * 2U);
                break;
            }
        }

        fCk = srcRate / postDiv;
    }

    return fCk;
}

#define MCU_STOP_SEC_CODE
#include "Mcu_MemMap.h"
/* End of file */
